﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Printing;
using System.Drawing;
using System.Security.Principal;

namespace Check_Printing_Solution
{
    public class PrintFileEngine
    {
        PrintManager manager = new PrintManager();
        TemplateLayout _template = new TemplateLayout();
        Bank _currentbank = new Bank();
        Customer _currentcustomer = new Customer();
        int chequesprinted = 0;
        int _chequecount = 0;
        int _coversprinted = 0;
        string _coverpage_nextchequenumber = "";
        string _lastchequenumber = "";
        int _incrementer = 0;
        int pagecount = 1;
        int _totalchequesprinted = 0;
        bool iscopy = false;
        PrintSelected printselected = null;

        public PrintFileEngine()
        { }

        public PrintFileEngine( PrintSelected printselectedform )
        {
            printselected = printselectedform;
        }

        private void Print( TemplateLayout styletemplate, int quantity, string printername )
        {
            //if there is no cheques per page in the template stop!
            if ( _template.ChquesPerPage == "0" || _template.ChquesPerPage == "" )
            {
                chequesprinted = quantity;
            }

            if ( !PrintRunner.StopPrint )
            {
                for ( int i = 0; i < quantity; i++ )
                {
                    if ( !PrintRunner.StopPrint )
                    {
                        PrintDocument template = new PrintDocument();
                        PrintController printcontroller = new StandardPrintController();
                        template.PrintController = printcontroller;

                        template.PrintPage += new PrintPageEventHandler( template_PrintPage );
                        template.PrinterSettings.PrinterName = printername;
                        template.DefaultPageSettings.PaperSize = new PaperSize( "Label Paper", _template.PaperWidth, _template.PaperHeight );

                        PaperSource papersource = new PaperSource();
                        papersource.SourceName = _template.Tray;
                        template.DefaultPageSettings.PaperSource = papersource;

                        //Set page orientation
                        if ( styletemplate.Landscape )
                        {
                            template.DefaultPageSettings.Landscape = true;
                        }
                        else
                        {
                            template.DefaultPageSettings.Landscape = false;
                        }

                        if ( _template.NoCopies == 3 )
                        {
                            //Cheque
                            template.Print();
                            _chequecount = _chequecount - Convert.ToInt32( _template.ChquesPerPage );
                            chequesprinted = chequesprinted - Convert.ToInt32( _template.ChquesPerPage );
                            pagecount = pagecount - 1;

                            iscopy = true;

                            //Copy 1
                            template.Print();
                            _chequecount = _chequecount - Convert.ToInt32( _template.ChquesPerPage );
                            chequesprinted = chequesprinted - Convert.ToInt32( _template.ChquesPerPage );
                            pagecount = pagecount - 1;

                            //Copy 2
                            template.Print();
                            _chequecount = _chequecount - Convert.ToInt32( _template.ChquesPerPage );
                            chequesprinted = chequesprinted - Convert.ToInt32( _template.ChquesPerPage );
                            pagecount = pagecount - 1;

                            //Copy 3
                            template.Print();

                            iscopy = false;
                        }
                        else if ( _template.NoCopies == 2 )
                        {
                            //Cheque
                            template.Print();
                            _chequecount = _chequecount - Convert.ToInt32( _template.ChquesPerPage );
                            chequesprinted = chequesprinted - Convert.ToInt32( _template.ChquesPerPage );
                            pagecount = pagecount - 1;

                            iscopy = true;

                            //Copy 1
                            template.Print();
                            _chequecount = _chequecount - Convert.ToInt32( _template.ChquesPerPage );
                            chequesprinted = chequesprinted - Convert.ToInt32( _template.ChquesPerPage );
                            pagecount = pagecount - 1;

                            //Copy 2
                            template.Print();

                            iscopy = false;
                        }
                        else if ( _template.NoCopies == 1 )
                        {
                            //Cheque
                            template.Print();
                            _chequecount = _chequecount - Convert.ToInt32( _template.ChquesPerPage );
                            chequesprinted = chequesprinted - Convert.ToInt32( _template.ChquesPerPage );
                            pagecount = pagecount - 1;

                            iscopy = true;

                            //Copy 1
                            template.Print();

                            iscopy = false;
                        }
                        else if ( _template.NoCopies == 0 )
                        {
                            iscopy = false;
                            template.Print();
                        }
                        else
                        {
                            template.Print();
                        }
                    }
                }
            }
        }

        void template_PrintPage( object sender, PrintPageEventArgs e )
        {
            int padding = 0;
            int chequeincrementer = 0;

            if ( !PrintRunner.StopPrint )
            {
                for ( int i = 0; i < Convert.ToInt32( _template.ChquesPerPage ); i++ )
                {
                    if ( !PrintRunner.StopPrint )
                    {
                        //i = Convert.ToInt32( _template.ChquesPerPage ) + 1;

                        int mychequenumber = 0;

                        if ( !_template.Skip )
                        {
                            mychequenumber = ( chequeincrementer + ( pagecount - 1 ) + Convert.ToInt32( _lastchequenumber ) );
                        }
                        else
                        {
                            mychequenumber = _totalchequesprinted + Convert.ToInt32( _lastchequenumber );
                        }

                        string checkno = string.Format( "C{0}C A{1}D{2}A {3}C  {4}", FormatSeqNumber( mychequenumber.ToString().Trim() ), _currentbank.BranchPrefix.Trim(), _currentbank.BranchCode.Trim(), _currentcustomer.ChequeNumber.Trim(), _template.DepositSlips.Trim() );
                        FontStyle fntstyle = FontStyle.Regular;

                        if ( _template.BoldNameCheque == true )
                        {
                            fntstyle = FontStyle.Bold;
                        }
                        else
                        {
                            fntstyle = FontStyle.Regular;
                        }

                        if ( _template.PrintNames )
                        {
                            e.Graphics.DrawString( _currentcustomer.FirstName + " " + _currentcustomer.LastName, new Font( _template.NameFont, Convert.ToSingle( _template.NameFontSize ), FontStyle.Bold ), Brushes.Black, new Point( Convert.ToInt32( _template.NameX ), Convert.ToInt32( _template.NameY ) + padding ) );
                        }
                        if ( _template.PrintNameAddress )
                        {
                            //Line 1
                            if ( _template.ItalicLine1Cheque )
                            {
                                e.Graphics.DrawString( _currentcustomer.Line1, new Font( _template.Address1Font, Convert.ToSingle( _template.Address1FontSize ), fntstyle | FontStyle.Italic ), Brushes.Black, new Point( Convert.ToInt32( _template.Address1X ), Convert.ToInt32( _template.Address1Y ) + padding ) );
                            }
                            else
                            {
                                e.Graphics.DrawString( _currentcustomer.Line1, new Font( _template.Address1Font, Convert.ToSingle( _template.Address1FontSize ), fntstyle ), Brushes.Black, new Point( Convert.ToInt32( _template.Address1X ), Convert.ToInt32( _template.Address1Y ) + padding ) );
                            }
                            //Line 2
                            if ( _template.ItalicLine2Cheque )
                            {
                                e.Graphics.DrawString( _currentcustomer.Line2, new Font( _template.Address2Font, Convert.ToSingle( _template.Address2FontSize ), FontStyle.Italic ), Brushes.Black, new Point( Convert.ToInt32( _template.Address2X ), Convert.ToInt32( _template.Address2Y ) + padding ) );
                            }
                            else
                            {
                                e.Graphics.DrawString( _currentcustomer.Line2, new Font( _template.Address2Font, Convert.ToSingle( _template.Address2FontSize ) ), Brushes.Black, new Point( Convert.ToInt32( _template.Address2X ), Convert.ToInt32( _template.Address2Y ) + padding ) );
                            }
                        }
                        if ( _template.PrintChequeNos )
                        {
                            FontFamily font = new FontFamily( _template.ChequeNumberFont.Trim() );
                            e.Graphics.DrawString( checkno, new Font( font, Convert.ToSingle( _template.ChequeNumberFontSize ), FontStyle.Regular, GraphicsUnit.Pixel ), Brushes.Black, new Point( Convert.ToInt32( _template.ChequeNumberX ), Convert.ToInt32( _template.ChequeNumberY ) + padding ) );
                        }

                        if ( _template.PrintStubNos )
                        {
                            e.Graphics.DrawString( FormatSeqNumber( mychequenumber.ToString() ), new Font( _template.ChequeCountFont, Convert.ToSingle( _template.ChequeCountFontSize ) ), Brushes.Black, new Point( Convert.ToInt32( _template.ChequeCountX ), Convert.ToInt32( _template.ChequeCountY ) + padding ) );
                        }

                        if ( _template.PrintStubNos2 )
                        {
                            e.Graphics.DrawString( FormatSeqNumber( mychequenumber.ToString() ), new Font( _template.StubFont, Convert.ToSingle( _template.StubSize ) ), Brushes.Black, new Point( Convert.ToInt32( _template.StubX ), Convert.ToInt32( _template.StubY ) + padding ) );
                        }

                        //Line 3
                        if ( _template.ItalicLine3Cheque )
                        {
                            e.Graphics.DrawString( _currentcustomer.Line3, new Font( _template.Address3Font, Convert.ToSingle( _template.Address3Size ), FontStyle.Italic ), Brushes.Black, new Point( Convert.ToInt32( _template.Address3X ), Convert.ToInt32( _template.Address3Y ) + padding ) );
                        }
                        else
                        {
                            e.Graphics.DrawString( _currentcustomer.Line3, new Font( _template.Address3Font, Convert.ToSingle( _template.Address3Size ) ), Brushes.Black, new Point( Convert.ToInt32( _template.Address3X ), Convert.ToInt32( _template.Address3Y ) + padding ) );
                        }

                        if ( _template.ItalicLine3Cheque )
                        {
                            e.Graphics.DrawString( _currentcustomer.Line4, new Font( _template.Address4Font, Convert.ToSingle( _template.Address4Size ), FontStyle.Italic ), Brushes.Black, new Point( Convert.ToInt32( _template.Address4X ), Convert.ToInt32( _template.Address4Y ) + padding ) );
                        }
                        else
                        {
                            e.Graphics.DrawString( _currentcustomer.Line4, new Font( _template.Address4Font, Convert.ToSingle( _template.Address4Size ) ), Brushes.Black, new Point( Convert.ToInt32( _template.Address4X ), Convert.ToInt32( _template.Address4Y ) + padding ) );
                        }
                        if ( _template.PrintBranchAddress )
                        {
                            e.Graphics.DrawString( _currentbank.BankAddress, new Font( _template.BankFont, Convert.ToSingle( _template.BankFontSize ) ), Brushes.Black, new Point( Convert.ToInt32( _template.BankX ), Convert.ToInt32( _template.BankY ) + padding ) );
                        }
                        padding = padding + Convert.ToInt32( _template.DistanceBetweenCheques );
                        _chequecount++;
                        chequesprinted++;
                        chequeincrementer = chequeincrementer + _incrementer;

                        //prevents incrementing for printing of copies
                        if ( iscopy == false )
                        {
                            _totalchequesprinted++;
                        }
                    }
                }
                pagecount++;
            }
        }

        bool _dearcustomerprinted = false;

        private void PrintCover( string printername )
        {
            chequesprinted = 0;

            PrintDocument template = new PrintDocument();
            PrintController printcontroller = new StandardPrintController();
            template.PrintController = printcontroller;

            template.QueryPageSettings += new QueryPageSettingsEventHandler( template_QueryPageSettings );
            template.PrintPage += new PrintPageEventHandler( covertemplate_PrintPage );
            template.PrinterSettings.PrinterName = printername;
            template.DefaultPageSettings.PaperSize = new PaperSize( "Label Paper", _template.PaperWidth, _template.PaperHeight );
            PaperSource papersource = new PaperSource();
            papersource.SourceName = _template.Tray;
            template.DefaultPageSettings.PaperSource = papersource;

            if ( !PrintRunner.StopPrint )
            {
                template.Print();
            }
            if ( _template.PrintDearCustomer == true && _dearcustomerprinted == false )
            {
                template.Print();
                _dearcustomerprinted = true;
            }
        }

        void template_QueryPageSettings( object sender, QueryPageSettingsEventArgs e )
        {
            if ( _template.Landscape )
            {
                e.PageSettings.Landscape = true;
            }
            else
            {
                e.PageSettings.Landscape = false;
            }
        }

        void covertemplate_PrintPage( object sender, PrintPageEventArgs e )
        {
            if ( !PrintRunner.StopPrint )
            {
                for ( int j = 0; j < _template.CoverCount; j++ )
                {
                    int padding = 0;

                    if ( !PrintRunner.StopPrint )
                    {
                        for ( int i = 0; i < Convert.ToInt32( _template.ChquesPerPage ); i++ )
                        {
                            FontStyle fntstyle = FontStyle.Regular;

                            if ( _template.BoldNameCover == true )
                            {
                                fntstyle = FontStyle.Bold;
                            }
                            else
                            {
                                fntstyle = FontStyle.Regular;
                            }

                            if ( _template.PrintBranchAddress )
                            {
                                e.Graphics.DrawString( _currentbank.BankAddress, new Font( _template.CoverAddress4Font, Convert.ToSingle( _template.CoverAddress4Size ) ), Brushes.Black, new Point( Convert.ToInt32( _template.CoverAddress4X ), Convert.ToInt32( _template.CoverAddress4Y ) + padding ) );
                            }
                            //Name
                            e.Graphics.DrawString( _currentcustomer.FirstName + " " + _currentcustomer.LastName, new Font( _template.CoverNameFont, Convert.ToSingle( _template.CoverNameSize ), FontStyle.Bold ), Brushes.Black, new Point( Convert.ToInt32( _template.CoverNameX ), Convert.ToInt32( _template.CoverNameY ) + padding ) );
                            //Address1
                            if ( _template.ItalicLine2Cover )
                            {
                                e.Graphics.DrawString( _currentcustomer.Line2, new Font( _template.CoverAddress1Font, Convert.ToSingle( _template.CoverAddress1Size ), FontStyle.Italic ), Brushes.Black, new Point( Convert.ToInt32( _template.CoverAddress1X ), Convert.ToInt32( _template.CoverAddress1Y ) + padding ) );
                            }
                            else
                            {
                                e.Graphics.DrawString( _currentcustomer.Line2, new Font( _template.CoverAddress1Font, Convert.ToSingle( _template.CoverAddress1Size ) ), Brushes.Black, new Point( Convert.ToInt32( _template.CoverAddress1X ), Convert.ToInt32( _template.CoverAddress1Y ) + padding ) );
                            }
                            //Address2
                            if ( _template.ItalicLine3Cover )
                            {
                                e.Graphics.DrawString( _currentcustomer.Line3, new Font( _template.CoverAddress2Font, Convert.ToSingle( _template.CoverAddress2Size ), FontStyle.Italic ), Brushes.Black, new Point( Convert.ToInt32( _template.CoverAddress2X ), Convert.ToInt32( _template.CoverAddress2Y ) + padding ) );
                            }
                            else
                            {
                                e.Graphics.DrawString( _currentcustomer.Line3, new Font( _template.CoverAddress2Font, Convert.ToSingle( _template.CoverAddress2Size ) ), Brushes.Black, new Point( Convert.ToInt32( _template.CoverAddress2X ), Convert.ToInt32( _template.CoverAddress2Y ) + padding ) );
                            }
                            //Phone
                            if ( _template.ItalicLine1Cover )
                            {
                                e.Graphics.DrawString( _currentcustomer.Line1, new Font( _template.CoverTelephoneFont, Convert.ToSingle( _template.CoverTelephoneSize ), fntstyle | FontStyle.Italic ), Brushes.Black, new Point( Convert.ToInt32( _template.CoverTelephoneX ), Convert.ToInt32( _template.CoverTelephoneY ) + padding ) );
                            }
                            else
                            {
                                e.Graphics.DrawString( _currentcustomer.Line1, new Font( _template.CoverTelephoneFont, Convert.ToSingle( _template.CoverTelephoneSize ), fntstyle ), Brushes.Black, new Point( Convert.ToInt32( _template.CoverTelephoneX ), Convert.ToInt32( _template.CoverTelephoneY ) + padding ) );
                            }
                            //Next Cheque #
                            e.Graphics.DrawString( FormatSeqNumber( _coverpage_nextchequenumber ), new Font( _template.CoverCheckCountFont, Convert.ToSingle( _template.CoverCheckCountSize ) ), Brushes.Black, new Point( Convert.ToInt32( _template.CoverCheckCountX ), Convert.ToInt32( _template.CoverCheckCountY ) + padding ) );
                            //CoverCheckCount

                            string checkno = string.Format( "C{0}C A{1}D{2}A {3}C  {4}", FormatSeqNumber( _coverpage_nextchequenumber ), _currentbank.BranchPrefix, _currentbank.BranchCode, _currentcustomer.ChequeNumber, _template.DepositSlips );
                            e.Graphics.DrawString( checkno, new Font( _template.CoverCheckNoFont, Convert.ToSingle( _template.CoverCheckNoSize ) ), Brushes.Black, new Point( Convert.ToInt32( _template.CoverCheckNoX ), Convert.ToInt32( _template.CoverCheckNoY ) + padding ) );

                            padding = padding + Convert.ToInt32( _template.DistanceBetweenCheques );
                        }
                    }
                    _coversprinted++;
                }
            }
        }

        public void InitiatePrint( string printername, Customer customer, Bank bank, string style,
            string comment, string nextchequenumber, string styleid, int numberbooks, int totalleaves, string filename, bool isreprint )
        {
            TemplateLayout template = manager.GetTemplateLayoutByStyle( style );
            _template = template;
            _currentcustomer = customer;
            _currentbank = bank;
            _lastchequenumber = nextchequenumber;

            int totalchequesforprint = totalleaves * numberbooks;
            _coverpage_nextchequenumber = ( Convert.ToInt32( nextchequenumber ) + totalleaves ).ToString();

            _incrementer = Convert.ToInt32( template.NoChequesPerBook );

            //Determine whether covers should be printed
            if ( template.PrintCovers )
            {
                //Send covers to be printed
                for ( int i = 0; i < Convert.ToInt32( template.CoverCount ); i++ )
                {
                    PrintCover( printername );
                }
            }
            if ( pagecount != 1 && !template.Skip )
            {
                pagecount = _totalchequesprinted + 1;
            }

            Print( template, totalleaves / Convert.ToInt32( _template.ChquesPerPage ), printername );
            chequesprinted = 0;
            _chequecount = 1;

            printselected.MarkRow( _currentcustomer.ChequeNumber, _currentcustomer.FirstName );

            CreateJobLog( comment,
                numberbooks.ToString(),
                nextchequenumber,
                customer.ChequeNumber,
                style, bank.BranchPrefix, bank.Name, numberbooks.ToString(), 
                filename, customer.FirstName, totalchequesforprint.ToString(), isreprint
                );
        }

        private string FormatSeqNumber( string seqnumber )
        {
            int templaterequired = Convert.ToInt32( _template.SeqNumberSize );
            int currentlength = seqnumber.ToString().Count();
            int gap = templaterequired - currentlength;
            string holder = "";

            for ( int i = 0; i < gap; i++ )
            {
                holder = holder + "0";
            }
            holder = holder + seqnumber;

            return holder;
        }

        private void CreateJobLog( string comment, string quantity, string lastchequenumber, string accountnumber, string chequetype,
            string bank, string branch, string numberbooks, string filename, string customername, string numbercheques, bool isreprint )
        {
            JobLog joblog = new JobLog();
            joblog.Comment = comment;
            joblog.DatePrinted = DateTime.Now;
            joblog.LastQuantity = quantity;
            joblog.LastChequeNumber = lastchequenumber;
            joblog.CustomerId = accountnumber;
            joblog.ChequeTypeId = chequetype;
            joblog.Bank = bank;
            joblog.Branch = branch;
            joblog.NumberBooks = numberbooks;
            joblog.Filename = filename;
            joblog.CustomerName = customername;
            joblog.PrintUser = WindowsIdentity.GetCurrent().Name.ToString();
            joblog.NumberCheques = numbercheques;
            joblog.IsReprint = isreprint;

            manager.AddJobLog( joblog );
        }
    }
}
